package com.dozen.commonbase.utils.id;

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Locale;

import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.provider.Settings.Secure;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;

import com.umeng.commonsdk.config.FieldManager;
import com.umeng.commonsdk.statistics.AnalyticsConstants;
import com.umeng.commonsdk.statistics.common.MLog;

public class GetDeviceId {

	private Context mContext;
	public GetDeviceId(Context context){
		mContext=context;
	}

	//cc 1 The IMEI
	//only useful for Android Phone(android.permission.READ_PHONE_STATE in Manifest)
	public String getIMEI(){
		//6.0前不作权限申请判断
		if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
			TelephonyManager TelephonyMgr = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
			@SuppressLint("HardwareIds") String szImei = TelephonyMgr.getDeviceId();
			return szImei;
		}
		return "";
	}

	//cc 2 Pseudo-Unique ID
	//useful for phone/pad
	public String getPUID(){
		String m_szDevIDShort = "35" + //make this look like a valid IMEI
				Build.BOARD.length()%10 +
				Build.BRAND.length()%10 +
				Build.CPU_ABI.length()%10 +
				Build.DEVICE.length()%10 +
				Build.DISPLAY.length()%10 +
				Build.HOST.length()%10 +
				Build.ID.length()%10 +
				Build.MANUFACTURER.length()%10 +
				Build.MODEL.length()%10 +
				Build.PRODUCT.length()%10 +
				Build.TAGS.length()%10 +
				Build.TYPE.length()%10 +
				Build.USER.length()%10 ; //13 digits
		return m_szDevIDShort;
	}

	//cc 3 Android ID
	//sometimes it will be null,cause this id can be changed by the manufacturer
	public String getAndroidId(){
		@SuppressLint("HardwareIds") String m_szAndroidID = Secure.getString(mContext.getContentResolver(), Secure.ANDROID_ID);
		return m_szAndroidID;
	}

	//cc 4 The WLAN MAC Address String
	//need android.permission.ACCESS_WIFI_STATE,or it will return null
	public String getWLANMAC(){
		String mac="";
		if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
			mac = getMacDefault(mContext);
		} else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
			mac = getMacAddress();
		} else {
			mac = getMacFromHardware();
		}
		return mac;
	}

	//cc 5 the BT MAC Address String
	//need android.permission.BLUETOOTH,or it will return null
	public String getBTMAC(){
		BluetoothAdapter m_BluetoothAdapter = null; // Local Bluetooth adapter
		m_BluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
		@SuppressLint("HardwareIds") String m_szBTMAC = m_BluetoothAdapter.getAddress();
		return m_szBTMAC;
	}

	//cc Combined Device ID
	public String getCombinedId(){
		String szImei=getIMEI();
		String m_szDevIDShort=getPUID();
		String m_szAndroidID=getAndroidId();
		String m_szWLANMAC=getWLANMAC();
		String m_szBTMAC=getBTMAC();
		String m_szLongID=szImei+m_szDevIDShort+m_szAndroidID+m_szWLANMAC+m_szBTMAC;
		Log.i("szImei","cccc|"+szImei);
		Log.i("m_szDevIDShort","cccc|"+m_szDevIDShort);
		Log.i("m_szAndroidID","cccc|"+m_szAndroidID);
		Log.i("m_szWLANMAC","cccc|"+m_szWLANMAC);
		Log.i("m_szBTMAC","cccc|"+m_szBTMAC);
		Log.i("m_szLongID","cccc|"+m_szLongID);
		// compute md5
		MessageDigest m = null;
		try {
			m = MessageDigest.getInstance("MD5");
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		m.update(m_szLongID.getBytes(),0,m_szLongID.length());
		// get md5 bytes
		byte p_md5Data[] = m.digest();
		// create a hex string
		String m_szUniqueID = new String();
		for (int i=0;i<p_md5Data.length;i++) {
			int b =  (0xFF & p_md5Data[i]);
			// if it is a single digit, make sure it have 0 in front (proper padding)
			if (b <= 0xF)
				m_szUniqueID+="0";
			// add number to string
			m_szUniqueID+=Integer.toHexString(b);
		}   // hex string to uppercase
		m_szUniqueID= m_szUniqueID.toUpperCase();
		return m_szUniqueID;
	}


	/**
	 * Android 6.0 之前（不包括6.0）获取mac地址
	 * 必须的权限 <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
	 * @param context * @return
	 */
	public static String getMacDefault(Context context) {
		String mac = "";
		if (context == null) {
			return mac;
		}
		WifiManager wifi = (WifiManager)context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
		WifiInfo info = null;
		try {
			info = wifi.getConnectionInfo();
		} catch (Exception e) {
			e.printStackTrace();
		}

		if (info == null) {
			return null;
		}
		mac = info.getMacAddress();
		if (!TextUtils.isEmpty(mac)) {
			mac = mac.toUpperCase(Locale.ENGLISH);
		}
		return mac;
	}

	/**
	 * Android 6.0-Android 7.0 获取mac地址
	 */
	public static String getMacAddress() {
		String macSerial = null;
		String str = "";

		try {
			Process pp = Runtime.getRuntime().exec("cat/sys/class/net/wlan0/address");
			InputStreamReader ir = new InputStreamReader(pp.getInputStream());
			LineNumberReader input = new LineNumberReader(ir);

			while (null != str) {
				str = input.readLine();
				if (str != null) {
					macSerial = str.trim();//去空格
					break;
				}
			}
		} catch (IOException ex) {
			// 赋予默认值
			ex.printStackTrace();
		}

		return macSerial;
	}

	/**
	 * Android 7.0之后获取Mac地址
	 * 遍历循环所有的网络接口，找到接口是 wlan0
	 * 必须的权限 <uses-permission android:name="android.permission.INTERNET"></uses-permission>
	 * @return
	 */
	public static String getMacFromHardware() {
		try {
			ArrayList<NetworkInterface> all =
					Collections.list(NetworkInterface.getNetworkInterfaces());
			for (NetworkInterface nif:all) {
				if (!nif.getName().equals("wlan0"))
					continue;
				byte[] macBytes = nif.getHardwareAddress();
				if (macBytes == null) return "";
				StringBuilder res1 = new StringBuilder();
				for (Byte b : macBytes) {
					res1.append(String.format("%02X:", b));
				}
				if (!TextUtils.isEmpty(res1)) {
					res1.deleteCharAt(res1.length() - 1);
				}
				return res1.toString();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		return "";
	}

	/**
	 * android 6.0+获取wifi的mac地址
	 * @param paramContext
	 * @return
	 */
	private static String getMacMoreThanM(Context paramContext) {
		try {
			//获取本机器所有的网络接口
			Enumeration enumeration = NetworkInterface.getNetworkInterfaces();
			while (enumeration.hasMoreElements()) {
				NetworkInterface networkInterface = (NetworkInterface)enumeration.nextElement();
				//获取硬件地址，一般是MAC
				byte[] arrayOfByte = networkInterface.getHardwareAddress();
				if (arrayOfByte == null || arrayOfByte.length == 0) {
					continue;
				}

				StringBuilder stringBuilder = new StringBuilder();
				for (byte b : arrayOfByte) {
					//格式化为：两位十六进制加冒号的格式，若是不足两位，补0
					stringBuilder.append(String.format("%02X:", new Object[] { Byte.valueOf(b) }));
				}
				if (stringBuilder.length() > 0) {
					//删除后面多余的冒号
					stringBuilder.deleteCharAt(stringBuilder.length() - 1);
				}
				String str = stringBuilder.toString();
				// wlan0:无线网卡 eth0：以太网卡
				if (networkInterface.getName().equals("wlan0")) {
					return str;
				}
			}
		} catch (SocketException socketException) {
			return null;
		}
		return null;
	}
}
